#include "matrix.h"
#include "grayimage.h"
#include <iostream>
#include <string>
#include <math.h>
#include <stdlib.h>

using namespace std;

int main (void)
{
    string ArqImg;
    cin >> ArqImg;
    int Orig1, Orig2, Dist1, Dist2;

    Matrix A ;
    Matrix X (8,1);
    Matrix L (8,1);
    Matrix T (3,3);
    A = zeros(8,8);
    int MaxOrig1 = 0, MaxOrig2 = 0;

    for (int i=0;i<4;i++)
    {
        cin >> Orig1 >> Orig2 >> Dist1 >> Dist2;
        if (Orig1>MaxOrig1)
            MaxOrig1 = Orig1;
        if (Orig2>MaxOrig2)
            MaxOrig2 = Orig2;
        L.put(2*i+1,1,Dist1);
        A.put(2*i+1,1,Orig1);  A.put(2*i+1,2,Orig2);  A.put(2*i+1,3, 1);  A.put(2*i+1,7, - Orig1*Dist1);  A.put(2*i+1,8,-Orig2*Dist1);
        L.put(2*i+2,1,Dist2);
        A.put(2*i+2,4,Orig1);  A.put(2*i+2,5,Orig2);  A.put(2*i+2,6, 1);  A.put(2*i+2,7, - Orig1*Dist2);  A.put(2*i+2,8,-Orig2*Dist2);
    }
    //cout << ArqImg <<endl;
    X = inverse(transpose(A)*A) * transpose(A) * L;

    T.put(1,1,X.get(1,1)); T.put(1,2,X.get(2,1));  T.put(1,3,X.get(3,1));
    T.put(2,1,X.get(4,1)); T.put(2,2,X.get(5,1));  T.put(2,3,X.get(6,1));
    T.put(3,1,X.get(7,1)); T.put(3,2,X.get(8,1));  T.put(3,3, 1.0);

    T.show();
    GrayImage ImgIn;
    ImgIn = loadPGM(ArqImg.c_str());
   // savePGM(ImgIn,"../T2.pgm",2,255);
    //ImgIn.show();
    GrayImage ImgOut(MaxOrig1+1,MaxOrig2+1);
    Matrix CoordinatesIn;
    Matrix CoordinatesOut(3,1); CoordinatesOut.put(3,1, 1.0);

    for (int x=0; x < (int)ImgOut.getRows(); x++)
        for (int y=0; y < (int)ImgOut.getCols(); y++)
        {
            CoordinatesOut.put(1,1, (double) x); CoordinatesOut.put(2,1, (double) y);
            CoordinatesIn = T * CoordinatesOut;
            double xIn = CoordinatesIn.get(1,1)/CoordinatesIn.get(3,1);
            double yIn = CoordinatesIn.get(2,1)/CoordinatesIn.get(3,1);
            //if (y==(-1+(int)ImgOut.getCols()))
            //   cout << "(" << x<< "," << y<< ")->   " << "(" << xIn<< "," << yIn<< ")   ";
            double A = 0, B = 0, pixel = 0;
            if ((floor(xIn)-ImgIn.getRows()<0)&&(floor(yIn)-ImgIn.getCols()<0)&&(floor(xIn)>=0)&&(floor(yIn)>=0))
                A+=ImgIn.getPixel(floor(xIn),floor(yIn))*(ceil(xIn)-xIn);
            if ((ceil(xIn)-ImgIn.getRows()<0)&&(floor(yIn)-ImgIn.getCols()<0)&&(ceil(xIn)>=0)&&(floor(yIn)>=0))
                A+= ImgIn.getPixel(ceil(xIn),floor(yIn))*(xIn-floor(xIn));
            if ((floor(xIn)-ImgIn.getRows()<0)&&(ceil(yIn)-ImgIn.getCols()<0)&&(floor(xIn)>=0)&&(ceil(yIn)>=0))
                B+=ImgIn.getPixel(floor(xIn),ceil(yIn))*(ceil(xIn)-xIn);
            if ((ceil(xIn)-ImgIn.getRows()<0)&&(ceil(yIn)-ImgIn.getCols()<0)&&(ceil(xIn)>=0)&&(ceil(yIn)>=0))
                B+= ImgIn.getPixel(ceil(xIn),ceil(yIn))*(xIn-floor(xIn));
            if ((ceil(yIn)-ImgIn.getCols()<0)&&(ceil(yIn)>=0))
                pixel += A*(ceil(yIn)-yIn) ;
            if (((floor(yIn)-ImgIn.getCols())<0)&&(floor(yIn)>=0))
                pixel += B*( (yIn-floor(yIn))) ;
            ImgOut.setPixel(x,y,(unsigned char) pixel);
           // if (!x&&!y)
           //     cout << endl<< "(" << x<< "," << y<< ")->   " << "(" << xIn<< "," << yIn<< ")   "<< " A " << A << " B " << B << " pixel" << pixel<<endl;

        }
   //ImgOut.show();
   // savePGM(ImgOut,"../Projetiva/EscorpiaoReconst.pgm",2,255);
}
